package com.yc.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import com.yc.config.AiConfig;
import com.yc.config.PersistentChatMemoryStore;
import com.yc.service.ScoreQueryService;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
import dev.langchain4j.service.TokenStream;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.FluxSink;

import java.util.*;

@CrossOrigin(origins = "http://localhost:8082")
@RestController
@RequestMapping("/ai")
@Slf4j
@Tag(name = "ai接口", description = "ai接口")
public class ChatController {
    @Autowired
    private ChatModel chatModel;
    @Autowired
    private StreamingChatModel streamingChatModel;
    @Autowired
    private AiConfig.Assistant assistant;
    @Autowired
    private RedisTemplate<String,String > redisTemplate;

    @Autowired
    PersistentChatMemoryStore persistentChatMemoryStore;


    @Autowired
    private ScoreQueryService scoreQueryService;


    @Operation(description = "聊天")
    @RequestMapping("/chat")
    public String chat(@RequestParam(defaultValue="message") String message){
        String answer = chatModel.chat(message);
        return answer;
    }

    @Operation(description = "流式聊天")
    @RequestMapping("/streamingchat")
    public void Streamingchat(@RequestParam(defaultValue="message") String message){
            streamingChatModel.chat(message, new StreamingChatResponseHandler() {
            @Override
            public void onPartialResponse(String s) {
                System.out.println(s);

            }

            @Override
            public void onCompleteResponse(ChatResponse chatResponse) {
                System.out.println(chatResponse.toString());
            }

            @Override
            public void onError(Throwable throwable) {
                System.out.println(throwable.toString());
            }
        });
    }

    @Operation(description = "流式聊天2")
    @RequestMapping(value="/streamingchat2",produces="text/stream;charset=UTF-8")
    public Flux<String> Streamingchat2(@RequestParam("message") String message){
        return Flux.create(fluxSink ->{
            streamingChatModel.chat(message, new StreamingChatResponseHandler() {
                @Override
                public void onPartialResponse(String s){
                    fluxSink.next(s);
                }

                @Override
                public void onCompleteResponse(ChatResponse chatResponse) {
                    fluxSink.complete();
                }

                @Override
                public void onError(Throwable throwable) {
                    fluxSink.error(throwable);
                }
            });
        });
    }

    @Operation(description = "引入ai助手聊天")
    @GetMapping( "/assistantchat")
    public String assistantchat(
            @RequestParam("message") String message,
            @RequestParam(value = "memoryId", defaultValue = "1") int memoryId
    ) {
        String answer = assistant.chat(memoryId, message);
        return answer;
    }
    @Operation(description = "引入ai助手流式聊天")
    @RequestMapping(value = "/assistantstreamingchat",produces="text/stream;charset=UTF-8")
    public Flux<String> assistantstreamingchat(@RequestParam("memoryId") int memoryId,
            @RequestParam("message") String message){
        TokenStream tokenStream =assistant.chatStream(memoryId,message);


        return Flux.create(fluxSink ->{
             tokenStream.onPartialResponse(s -> fluxSink.next(s))
                        .onCompleteResponse(r -> fluxSink.complete())
                        .onError(t -> fluxSink.error(t))
                        .start();
        }, FluxSink.OverflowStrategy.BUFFER);
        }

    @Operation(description = "获取所有会话id")
    @GetMapping("/allchat")
    public ResponseEntity<List<Integer>> allChat() {
        try {
            // 获取所有 chat:memory 前缀的键
            Set<String> keys = redisTemplate.keys("chat:memory*");

            // 如果没有找到任何键，返回空列表
            if (keys == null || keys.isEmpty()) {
                return ResponseEntity.ok(new ArrayList<>());
            }

            // 提取所有键中的会话ID
            List<Integer> memoryIds = new ArrayList<>();
            for (String key : keys) {
                // 提取 memoryId，假设 key 格式为 "chat:memory123"
                String memoryIdStr = key.substring("chat:memory".length());
                try {
                    int memoryId = Integer.parseInt(memoryIdStr);
                    memoryIds.add(memoryId);
                } catch (NumberFormatException e) {
                    // 如果键格式不正确，跳过
                    continue;
                }
            }

            // 返回会话ID列表
            return ResponseEntity.ok(memoryIds);
        } catch (Exception e) {
            // 处理异常，返回错误信息
            return ResponseEntity.status(500).body(List.of());
        }
    }



    @Operation(description = "根据id获取历史记录")
   // 获取会话历史记录
    @GetMapping("/gethistory/{memoryId}")
    public ResponseEntity<List<SimpleChatMessage>> getChatHistory(@PathVariable int memoryId) {
        try {
            String key = "chat:memory" + memoryId;
            String messageJson = redisTemplate.opsForValue().get(key);

            if (messageJson == null || messageJson.isEmpty()) {
                return ResponseEntity.ok(Collections.emptyList());
            }

            // 解析并转换为简化消息格式
            List<SimpleChatMessage> messages = parseChatMessages(messageJson);
            return ResponseEntity.ok(messages);
        } catch (Exception e) {
            log.error("获取聊天历史失败，memoryId: {}", memoryId, e);
            return ResponseEntity.status(500).build();
        }
    }




    // 解析复杂消息结构为简化格式
    private List<SimpleChatMessage> parseChatMessages(String json) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        JsonNode rootNode = mapper.readTree(json);

        List<SimpleChatMessage> simpleMessages = new ArrayList<>();

        for (JsonNode node : rootNode) {
            String type = node.get("type").asText();
            String content = extractContent(node);

            String sender;
            switch (type) {
                case "SYSTEM":
                    sender = "系统";
                    break;
                case "USER":
                    sender = "用户";
                    break;
                case "AI":
                    sender = "AI";
                    break;
                case "TOOL_EXECUTION_RESULT":
                    sender = "工具";
                    break;
                default:
                    sender = type;
            }

            simpleMessages.add(new SimpleChatMessage(sender, content));
        }

        return simpleMessages;
    }

    // 从不同类型的消息中提取内容
    private String extractContent(JsonNode node) {
        String type = node.get("type").asText();

        switch (type) {
            case "SYSTEM":
                return node.get("text").asText();

            case "USER":
                JsonNode contents = node.get("contents");
                if (contents.isArray() && contents.size() > 0) {
                    JsonNode firstContent = contents.get(0);
                    if (firstContent.has("text")) {
                        return firstContent.get("text").asText();
                    }
                }
                return "[用户消息]";

            case "AI":
                if (node.has("text")) {
                    return node.get("text").asText();
                }
                return "[AI 回复]";

            case "TOOL_EXECUTION_RESULT":
                if (node.has("text")) {
                    return node.get("text").asText();
                }
                return "[工具执行结果]";

            default:
                return node.toString();
        }
    }
    public class SimpleChatMessage {
        private String sender;    // 发送人：SYSTEM/USER/AI/TOOL
        private String content;   // 消息内容

        // 构造函数
        public SimpleChatMessage(String sender, String content) {
            this.sender = sender;
            this.content = content;
        }

        // Getter 和 Setter
        public String getSender() { return sender; }
        public void setSender(String sender) { this.sender = sender; }

        public String getContent() { return content; }
        public void setContent(String content) { this.content = content; }
    }
}
